﻿Imports System.Media
Imports WumpusWorld_2._0.Functions
Imports WumpusWorld_2._0.Domain
Imports WumpusWorld_2._0.Functions.Agent        ' Must import this to get agent_direction
Imports MicrosoftResearch.Infer                 ' These are used for probability
Imports MicrosoftResearch.Infer.Models
Imports MicrosoftResearch.Infer.Distributions

Imports System.Drawing.Color
Imports System.Media.SystemSound

Public Class MainWindow

#Region " Variables "
    Public WumpusAlive As Boolean = True
    Public TotScore As Integer = 1000
    Private _settings As Settings

    Private _objWorldGenerator As GenerateWorld

    Private _wumpusWorld As Cells
    Private KB As Cells

    Friend WithEvents AnAgent As Agent 'Object that captures events sent from the agent-object

#End Region

#Region " Load "

    Private Sub MainWindow_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'TODO: lyd are odin arrow | lyd wumpus 
        'TODO: ((((utility: gå hjem vs å lete videre etter og drepe wumpus))))
        
        AnAgent = New Agent
        AnAgent.points = 1000

        Loading()

        'TODO: Intro Music
        'Dim s As New SoundPlayer
        's.SoundLocation = "c:\chainsaw.wav"
        's.Play()
    End Sub

    Private Sub Loading()

        loadSettings() ' Load settings that is set before each game

        _objWorldGenerator = New GenerateWorld()

        _wumpusWorld = New Cells()
        KB = New Cells()

        'sets panelsize based on worldsize
        pnlWumpusWorld.Height = _settings.gridSize * _settings.picSizeHeight + 20       'Additional 20 for frame
        pnlWumpusWorld.Width = _settings.gridSize * _settings.picSizeWidth + 20
        pnlWumpusWorld.BackColor = Black
        pnlWumpusWorld.Visible = False                                                  ' Visible is set false. We use it for training purposes.
        
        pnlKB.Height = _settings.gridSize * _settings.picSizeHeight + 20
        pnlKB.Width = _settings.gridSize * _settings.picSizeWidth + 20
        pnlKB.BackColor = Black

        lblPoints.Text = AnAgent.points

        'Fills the arrays up with information and pictures
        _wumpusWorld.cellArray = _objWorldGenerator.generateArray(_settings)
        KB.cellArray = _objWorldGenerator.generateArray(_settings)

        'setting agent in cell 1,1
        _wumpusWorld.cellArray(0, _settings.gridSize - 1).hasAgent = True

        ' Setting additional gamerules
        With KB.cellArray(0, _settings.gridSize - 1)
            .hasAgent = True
            .hasPit = False
            .hasWumpus = False
            .isVisited = True
        End With

        'generating world based on settings
        _wumpusWorld.cellArray = _objWorldGenerator.GenerateBoard(_settings, _wumpusWorld.cellArray)

        ' Give perceptions to KB from Wumpusworld
        _objWorldGenerator.updateKBInfo(_wumpusWorld, KB)

        'generating pictures based on world
        _objWorldGenerator.GeneratePictures(_wumpusWorld.cellArray, _settings, AnAgent, "World")
        _objWorldGenerator.GeneratePictures(KB.cellArray, _settings, AnAgent, "KB")

    End Sub

    Private Sub loadSettings()

        _settings = New Settings()

        If rbAI.Checked Then
            _settings.player = True
        End If

        If rbPlayer.Checked Then
            _settings.player = False
        End If

        If rbEasy.Checked Then
            _settings.probPit = 0.15
        End If

        If rbIntermediate.Checked Then
            _settings.probPit = 0.2
        End If

        If rbDifficult.Checked Then
            _settings.probPit = 0.25
        End If

        If rbImpossible.Checked Then
            _settings.probPit = 0.5
        End If

        If rbSmall.Checked Then
            _settings.gridSize = 4
        End If

        If rbMedium.Checked Then
            _settings.gridSize = 7
        End If

        If rbLarge.Checked Then
            _settings.gridSize = 10
        End If

        _settings.probWumpus = 0.05
        _settings.probGold = 0.05
        _settings.picSizeHeight = 75 'pixels
        _settings.picSizeWidth = 75 'pixels


        With Me
            .WindowState = Windows.Forms.FormWindowState.Maximized
            .Timer_Clock.Interval = 3000
            .Timer_Clock.Enabled = True

            .btnReset.Focus()
        End With

        AnAgent.Direction = AgentDirection.Right
        AnAgent.hasArrow = True
        AnAgent.isAlive = True
        AnAgent.hasGold = False
        AnAgent.hasWon = False

    End Sub

#End Region

#Region " KeyEvents "

    Private Sub btnReset_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles btnReset.PreviewKeyDown

        ''listener'objekt??? må være tilstede for at knappen skal ta til seg at det trykkes på noen knapper
        'deretter kan keydown event kjøres på disse

        Select Case (e.KeyCode)
            Case Keys.Up, Keys.Right, Keys.Left, Keys.Down, Keys.G
                e.IsInputKey = True
        End Select
    End Sub

    Private Sub Button1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles btnReset.KeyDown
        ' Changes coordinates of active cell in KB.
        If AnAgent.isAlive Then
            If AnAgent.hasWon = False Then

                Select Case e.KeyValue
                    Case Keys.Right
                        AnAgent.TurnRight()
                    Case Keys.Left
                        AnAgent.TurnLeft()
                    Case Keys.Up
                        Select Case AnAgent.Direction
                            'Move functions are run on both KB and the World to make them both updated
                            Case AgentDirection.Right
                                AnAgent.MoveRight(KB.cellArray)
                                AnAgent.MoveRight(_wumpusWorld.cellArray)
                            Case AgentDirection.Down
                                AnAgent.MoveDown(KB.cellArray)
                                AnAgent.MoveDown(_wumpusWorld.cellArray)
                            Case AgentDirection.Left
                                AnAgent.MoveLeft(KB.cellArray)
                                AnAgent.MoveLeft(_wumpusWorld.cellArray)
                            Case AgentDirection.Up
                                AnAgent.MoveUp(KB.cellArray)
                                AnAgent.MoveUp(_wumpusWorld.cellArray)
                        End Select
                    Case Keys.Down
                        'When we shoot at the wumpus, we run this function against the real world
                        AnAgent.Shoot(_wumpusWorld.cellArray)
                    Case Keys.G
                        'When we grab the gold, this must be updated in bot the world and the KB
                        AnAgent.GrabGold(_wumpusWorld.cellArray, KB.cellArray)

                End Select
                UpdateKBAfterMove()

            End If
        End If

    End Sub

    Private Sub UpdateKBAfterMove()

        'Update KB after moving
        _objWorldGenerator.updateKBInfo(_wumpusWorld, KB)

        'Get current active cell, to test if it has a wumpus or a pit
        Dim currentActiveCell As New Cell
        currentActiveCell = KB.getActiveCell(KB.cellArray)

        'These functions updates the panels. The string in the end specifies which
        _objWorldGenerator.UpdatePictures(_wumpusWorld.cellArray, AnAgent, "World")
        _objWorldGenerator.UpdatePictures(KB.cellArray, AnAgent, "KB")

        'This event ends the game if the agent gets killed or gets to 1.1 with the gold
        AnAgent.EventGenerator(currentActiveCell, _settings.gridSize)

        'Point label gets updated. The actual score is treated in the agent class
        lblPoints.Text = AnAgent.points.ToString()

    End Sub

#End Region

#Region "Other Events"

    Private Sub AgentSender_KilledByWumpus(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.KilledByWumpus

        RevealWorld()

        Me.lbGameinfo.Items.Add("You were killed by the Wumpus Mohahaha")

        MsgBox("You were killed by the Wumpus Mohahaha")
    End Sub
    Private Sub AgentSender_KilledByPit(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.KilledByPit
        Me.lbGameinfo.Items.Add("You fell into a Pit")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        RevealWorld()
        'MsgBox("You were killed by the Pit Mohahaha")
    End Sub
    Private Sub AgentSender_OutOfBound(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.OutOfBound
        Me.lbGameinfo.Items.Add("Out Of Bounds Bugger")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        'MsgBox("Out Of Bounds Bugger")
    End Sub
    Private Sub AgentSender_OutOfAmmo(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.OutOfAmmo
        Me.lbGameinfo.Items.Add("Out Of Ammo")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        'MsgBox("Out Of Ammo")
    End Sub
    Private Sub AgentSender_ShotOutside(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.ShotOutside
        Me.lbGameinfo.Items.Add("You just shot your arrow outside world")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        'MsgBox("You just shot your arrow outside world")
    End Sub
    Private Sub AgentSender_WumpusKilled(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.WumpusKilled
        Me.lbGameinfo.Items.Add("You killed the Wumpus :)")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        ' MsgBox("You killed the Wumpus :)")
    End Sub
    Private Sub AgentSender_WumpusMissed(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.WumpusMissed
        Me.lbGameinfo.Items.Add("You suck at shooting!!! Missed me you fucker!!!!")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        ' MsgBox("You suck at shooting!!! Missed me you fucker!!!!")
    End Sub
    Private Sub AgentSender_GrabbedGold(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.GrabbedGold
        Me.lbGameinfo.Items.Add("You grabbed the gold")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        ' MsgBox("You grabbed the gold")
    End Sub
    Private Sub AgentSender_GoldNotFound(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.GoldNotFound
        Me.lbGameinfo.Items.Add("There is no gold here")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        'MsgBox("There is no gold here")
    End Sub
    Private Sub AgentSender_Won(ByVal sender As Object, ByVal e As EventArgs) Handles AnAgent.Won
        Me.lbGameinfo.Items.Add("You won the game")
        Me.lbGameinfo.TopIndex = Me.lbGameinfo.Items.Count - 1
        RevealWorld()
        ' MsgBox("You won the game")
    End Sub

#End Region

    Private Sub RevealWorld()
        ' Reset KB and import the true world.
        ResetKB(KB.cellArray)
        KB.cellArray = _wumpusWorld.cellArray
        _objWorldGenerator.UpdatePictures(KB.cellArray, AnAgent, "KB")
        Me.pnlWumpusWorld.Visible = False
        'TODO: "Fix this problem :)"

    End Sub

    Private Sub ResetWorld(ByVal world(,) As Cell, ByVal KB(,) As Cell)

        For Each cell In world
            cell.resetCell(cell)
            cell.setBreezeLabel(Visible = False)
            cell.setStenchLabel(Visible = False)
            cell.setGlitterLabel(Visible = False)
            cell.setVisitedLabel(Visible = False)
            'PicBox has to be invisible to make loading work
            cell.picBox.Visible = False
        Next
        WumpusAlive = True
        '_objWorld.UpdatePictures(world, AnAgent, "World")

        For Each cell In KB
            cell.resetCell(cell)
            cell.setBreezeLabel(Visible = False)
            cell.setStenchLabel(Visible = False)
            cell.setGlitterLabel(Visible = False)
            cell.setVisitedLabel(Visible = False)
            'PicBox has to be invisible to make loading work
            cell.picBox.Visible = False
        Next

    End Sub
    Private Sub ResetKB(ByVal KB(,) As Cell)


        For Each cell In KB
            cell.resetCell(cell)
            cell.setBreezeLabel(Visible = False)
            cell.setStenchLabel(Visible = False)
            cell.setGlitterLabel(Visible = False)
            cell.setVisitedLabel(Visible = False)
            'PicBox has to be invisible to make loading work
            cell.picBox.Visible = False
        Next

    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click

        ResetWorld(_wumpusWorld.cellArray, KB.cellArray)

        Loading()

    End Sub
    Dim sec As Long


    Private Sub Timer_Clock_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer_Clock.Tick

        sec = sec + 1

        If AnAgent.isAlive Then
            If AnAgent.hasWon = False Then

                'AnAgent.MoveRight(KB.cellArray)
                'AnAgent.MoveRight(_wumpusWorld.cellArray)

                'UpdateAfterMove()

            End If
        End If


        Me.Lbl_Clock.Text = sec
    End Sub
    'TODO: timer

    Sub tt()
        Dim t As New Timer
        t.Enabled = True
        t.Interval = 50
        t.Start()

    End Sub

    'TODO:make timer min sec -> if value = 60 then = 0 and min+=1
    'TODO: sjekk om spillet er i gang for å handle at man trykkre på start før stopp? spm om man vil avbryte nåværende spill?

    

End Class